using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using UCS.XNA.Draughts.Pieces;
using UCS.XNA.Draughts.Squares;
using UCS.XNA.Utils;

namespace UCS.XNA.Draughts.Boards
{
    public class Board
    {
        #region Attributes and Properties

        private Square[,] _squares;
        public Square[,] Squares
        {
            get { return _squares; }
        }

        #endregion

        #region Indexer

        public Square this[BoardPosition boardPosition]
        {
            get
            {
                if (boardPosition.I >= 0 && boardPosition.J >= 0 && boardPosition.I < 8 && boardPosition.J < 8)
                    return this._squares[boardPosition.I, boardPosition.J];

                return null;
            }
        }

        #endregion

        #region Constructors

        public Board()
        {
            this.InitializeSquares();
            this.InitializePieces();
        }

        #endregion

        #region Private Methods

        private void InitializeSquares()
        {
            this._squares = new Square[8, 8];

            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    var type = (i + j) % 2 == 0 ? SquareType.White : SquareType.Black;
                    var position = new BoardPosition(i, j);

                    this._squares[i, j] = new Square(type, position);
                    this._squares[i, j].InitializeTextures();
                }
            }
        }

        private void InitializePieces()
        {
            if (this._squares == null)
                return;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    var square = this._squares[i, j];
                    if (square.Type == SquareType.Black)
                        square = this._squares[i + 5, j];

                    var piece = null as Piece;
                    var pieceColor = square.Type == SquareType.Black ? PieceColor.Black : PieceColor.White;

                    piece = new CommonPiece(pieceColor, square.BoardPosition);
                    piece.InitializeTextures();
                    square.Piece = piece;
                }
            }

            //this.InitializePieceAt(1, 2, PieceColor.Black, true);
            //this.InitializePieceAt(4, 1, PieceColor.White, true);
            //this.InitializePieceAt(2, 1, PieceColor.White, true);
            //this.InitializePieceAt(7, 0, PieceColor.White, true);
        }

        private void InitializePieceAt(int i, int j, PieceColor color, bool common)
        {
            Square square = this._squares[i, j];
            Piece piece = null;
            if (color == PieceColor.Black)
            {
                if (common)
                {
                    piece = new CommonPiece(PieceColor.Black, square.BoardPosition);
                    piece.InitializeTextures();
                }
                else
                {
                    piece = new QueenPiece(PieceColor.Black, square.BoardPosition);
                    piece.InitializeTextures();
                }
            }
            else
            {
                if (common)
                {
                    piece = new CommonPiece(PieceColor.White, square.BoardPosition);
                    piece.InitializeTextures();
                }
                else
                {
                    piece = new QueenPiece(PieceColor.White, square.BoardPosition);
                    piece.InitializeTextures();
                }
            }

            square.Piece = piece;
        }

        private void UpdateSquares(GameTime gameTime)
        {
            for (int i = 0; i < 8; i++)
                for (int j = 0; j < 8; j++)
                    this._squares[i, j].Update(gameTime);
        }

        private void DrawSquares(GameTime gameTime)
        {
            for (int i = 0; i < 8; i++)
                for (int j = 0; j < 8; j++)
                    this._squares[i, j].Draw(gameTime);
        }

        #endregion

        #region Public Methods

        public IEnumerable<Piece> GetPieces(PieceColor color)
        {
            List<Piece> pieces = new List<Piece>();

            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    Piece piece = _squares[i, j].Piece;
                    if (piece != null && piece.Color == color)
                        pieces.Add(piece);
                }
            }

            return pieces;
        }

        public void Update(GameTime gameTime)
        {
            this.UpdateSquares(gameTime);
        }

        public void Draw(GameTime gameTime)
        {
            GameResources.SpriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);

            this.DrawSquares(gameTime);

            GameResources.SpriteBatch.End();
        }

        #endregion
    }
}
